/**
 * @Title SysUtil.java
 * @Package com.eppear.jpfm.framework.util
 * @Description
 * @author JianFeng Zhang(张建锋)
 * @date 2016-12-27 上午1:18:17
 * @version 
 */
package com.eppear.jpfm.framework.util;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;
import org.springframework.util.StringUtils;

import com.eppear.jpfm.framework.constants.Constants;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * @ClassName SysUtil
 * @Description
 *         系统工具类
 * @author JianFeng Zhang(张建锋)
 * @date   2016-12-27 上午1:18:17
 *
 */
public class SysUtil {

	private static Logger log =LoggerFactory.getLogger(SysUtil.class);
	
	/**
	 * @Title renderJson
	 * @Description 将 obj转化成Json返回到页面
	 * @param res 客户端的响应体
	 * @param obj 需要转化的对象
	 */
	public static void renderJson(HttpServletResponse res, Object obj) {
		PrintWriter out=null;
		try{
			 /* 设置格式为text/json    */
			res.setContentType("text/json"); 
            /*设置字符集为'UTF-8'*/
			res.setCharacterEncoding(Constants.SYS_ENCODE); 
            
			out = res.getWriter();
			out.print(toJson(obj));
			out.flush();
		}catch (IOException e) {
			log.error("Json返回到页面出错,详细信息:{}",e.getMessage());
			//throw new MyException(Constants.ERROR_CODE_1000,"Json返回到页面出错!");			
		}finally {
			if (out != null) {
				out.close();
			}
		}
	}
	
	/**
	 * @Title isAjax
	 * @Description 是否是Ajax请求
	 * @param req
	 * @return true 或 false
	 */
	public static boolean isAjax(HttpServletRequest req) {
		String ajaxHaeder = req.getHeader("X-Requested-With");
		return (ajaxHaeder != null && "XMLHttpRequest".equals(ajaxHaeder));
	}
	
	/**
	 * @Title isSmartPhone
	 * @Description 判断客户端是否是智能手机
	 * @param request
	 * @return
	 */
	public static boolean isSmartPhone(HttpServletRequest request) {
		boolean flag = false;

		String agent = request.getHeader("User-Agent");
		String[] keywords = {
				"Android", "iPhone", "iPod", "iPad", "Windows Phone", "MQQBrowser"
		};
		// 排除 Windows 桌面系统
		if (!isExisted(agent, "Windows NT")
				|| (isExisted(agent, "Windows NT") && isExisted(agent, "compatible; MSIE 9.0;"))) {
			// 排除 苹果桌面系统
			if (!isExisted(agent, "Windows NT") && !isExisted(agent, "Macintosh")) {
				for (String str : keywords) {
					if (isExisted(agent, str)) {
						flag = true;
						break;
					}
				}
			}
		}

		return flag;
	}
	
	/**
	 * @Title isExisted
	 * @Description 判断一个字符串中是否包含指字的子串
	 * @param str 目标字符串
	 * @param subStr 子字符串
	 * @return
	 */
	public static boolean isExisted(String str, String subStr) {
		if (StringUtils.isEmpty(str) || StringUtils.isEmpty(subStr)) {
			return false;
		}

		if (str.indexOf(subStr) >= 0) {
			return true;
		}

		return false;
	}
	
	/**
	 * @Title getMapkeyByValue
	 * @Description 根据Map中的Value获取key,返回找到的第一个
	 * @param map 要查找的Map
	 * @param obj 需要查找value
	 * @return
	 */
	public static Object getMapkeyByValue(Map map, Object obj) {
		
		if (map == null || map.isEmpty()) {
			return null;
		}
		Set set = map.entrySet();
		Iterator it = set.iterator();
		while (it.hasNext()){
			Map.Entry entry = (Map.Entry) it.next();
			if (entry.getValue().equals(obj)) {
				return entry.getKey();
			}
		}
		return null;
	}
	
	/**
	 * @Title encoder
	 * @Description 字符串加密
	 * @param s 明文
	 * @return 密文
	 */
	public static String encoder(String s) {
		Md5PasswordEncoder md5 = new Md5PasswordEncoder();
		String newS= md5.encodePassword(s, null);
		return newS;
	}
	
	/**
	 * 将java对象转成json的方法
	 * @param o
	 * @return
	 */
	public static String toJson(Object o){
		String ret =null;
		ObjectMapper mapper = new ObjectMapper();
		//设置日期格式  
		SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
		mapper.setDateFormat(fmt);  
		try {
			ret = mapper.writeValueAsString(o);
		} catch(Exception e){
			log.error(e.getMessage());
		}
		return ret;
	}
	
	/**
	 * @Description
	 *  把JSON字符串,转化成指字的JAVA类实例
	 * @author JianFeng Zhang(张建锋)
	 * @date 2017-03-14 下午11:50:09
	 * @param content  json字符串
	 * @param valueType JAVA类型 如 XXX.class
	 * @return
	 */
	public static<T> T jsonString2Obj(String content, Class<T> valueType){
		T ret = null;
		ObjectMapper mapper = new ObjectMapper(); 
		try {
			ret = mapper.readValue(content, valueType);
		} catch(Exception e){
			log.error(e.getMessage());
		}
		return ret;
	}
	
	/**
	 * 判断一个字符串变量是为空, null 或空串都算空
	 * @param str 需要判断的字符串
	 * @return 为空时,返回true,不为空时返回false
	 */
	public static boolean isEmpty(String str) {
		boolean r= false;
		if(str ==null || str.length()<=0)
			r=true;
		
		return r;
	}
	
	/**
	 * 对一个字符串两端去空格后,判断是为空, null 或空串都算空
	 * @param str 需要判断的字符串
	 * @return 为空时,返回true,不为空时返回false
	 */
	public static boolean isEmptyWithTrim(String str) {
		boolean r= false;
		if(str ==null || str.trim().length()<=0)
			r=true;
		
		return r;
	}
	/**
     * 取出一个指定长度大小的随机正整数.
     * 
     * @param length
     *            int 设定所取出随机数的长度。length小于11
     * @return int 返回生成的随机数。
     */
    public static int buildRandom(int length) {
        int num = 1;
        double random = Math.random();
        if (random < 0.1) {
            random = random + 0.1;
        }
        for (int i = 0; i < length; i++) {
            num = num * 10;
        }
        return (int) ((random * num));
    }
}
